<h1>PARTICLES DOCUMENTATION </br>Version: 1.21.70.3</h1>
<h2><p id="Index">索引</p></h2>
<table border="1">
<tr> <th><a href="#Basic Structure Overview">基本结构概述</a></th> </tr>
<tr> <th><a href="#Component Concept">组件概念</a></th> </tr>
<tr> <th><a href="#Current Component List">当前组件列表</a></th> </tr>
<tr> <td> <a href="#"> </a> </tr> </td>
<tr> <td> <a href="#Emitter Components">发射器组件</a> </tr> </td>
<tr> <td> <a href="#Particle Components">粒子组件</a> </tr> </td>
<tr> <th><a href="#Curves">曲线</a></th> </tr>
<tr> <th><a href="#Events">事件</a></th> </tr>
<tr> <th><a href="#Examples">示例</a></th> </tr>
<tr> <td> <a href="#Bouncing Bubbles">弹跳气泡</a> </tr> </td>
<tr> <td> <a href="#Flame particle">火焰粒子</a> </tr> </td>
<tr> <td> <a href="#Mob Flame effect">生物火焰效果</a> </tr> </td>
<tr> <td> <a href="#Smoke particle">烟雾粒子</a> </tr> </td>
<tr> <th><a href="#Materials">材质</a></th> </tr>
<tr> <td> <a href="#"> </a> </tr> </td>
<tr> <th><a href="#Molang integration">Molang集成</a></th> </tr>
<tr> <td> <a href="#"> </a> </tr> </td>
<tr> <th><a href="#Namespacing">命名空间</a></th> </tr>
<tr> <th><a href="#Particles Entity Integration">粒子的实体集成</a></th> </tr>
<tr> <td> <a href="#Animation Controller effects">动画控制器效果</a> </tr> </td>
<tr> <td> <a href="#Animation Controller effects (continued)">动画控制器效果（持续）</a> </tr> </td>
<tr> <td> <a href="#Animation Timeline effects">动画时间轴效果</a> </tr> </td>
<tr> <td> <a href="#Animation Timeline effects (continued)">动画时间轴效果（持续）</a> </tr> </td>
<tr> <td> <a href="#Effect Event">效果事件</a> </tr> </td>
<tr> <td> <a href="#Effect List">效果列表</a> </tr> </td>
<tr> <td> <a href="#Effect List (continued)">效果列表（持续）</a> </tr> </td>
<tr> <th><a href="#Particles Examples Pack">粒子示例包</a></th> </tr>
<tr> <td> <a href="#"> </a> </tr> </td>
<tr> <th><a href="#Structure In Detail">详细的结构</a></th> </tr>
</table>
<a href="#Index">返回顶部</a>
<h1><p id="Basic Structure Overview">基本结构概述</p></h1>

粒子特效由基本渲染参数和一组组件组成。组件可以按任何顺序放置。</br><h2></h2>
纲要：<br / ><textarea readonly="true" cols="119" rows="32">
{
  "format_version": "1.10.0",
  "particle_effect": {
    "description": {
      "identifier": <string>, // e.g. "minecraft:test_effect", this is the name the particle emitter is referred to as
      "basic_render_parameters": {
          "material": <string> // Minecraft material to use for emitter
          "texture": <string> // Minecraft texture to use for emitter
      }
    },
    "curves": {
      // curve details
    },
    "events": {
      // events details
    },
    "components": 
      // emission rate components

      // emission lifetime components

      // emission shape components, or the shape of the effect as defined
      // by particle emission position and directions

      // emitter local space components

      // components that control initial state of particles

      // components that control/direct motion of particles

      // components that affect how the particle is drawn

      // components that affect particle lifetime
    }
  }
}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h1><p id="Component Concept">组件概念</p></h1>

粒子系统是基于组件的。这意味着粒子特效是通过一组组件组成的。为了让效果执行某些作，您需要添加一个组件来处理效果的该方面。例如，发射器通常需要具有其生命周期的规则，因此效果应具有一个或多个生命周期组件，用于处理发射器和发射粒子的生命周期任务。</br></br>这个想法是后续可以添加新的组件，并且可以在有意义的情况下将组件组合起来以获得不同的行为。例如，一个粒子可能有一个动态组件用于移动，还有一个碰撞组件用于处理与地形的交互。</br></br>将组件视为告诉粒子系统您希望发射器或粒子做什么，而不是公开粒子参数列表并必须整理这些参数才能获得所需的行为。</br><a href="#Index">返回顶部</a><br><br>

<h1><p id="Current Component List">当前组件列表</p></h1>

<h2></h2>
对于这些组件中的字段，使用以下缩写：<br / ><textarea readonly="true" cols="107" rows="7">
<float> - 字段采用浮点输入
<float/molang> - 字段采用浮点输入或 Molang 表达式
<default:val> - 指定在未指定字段时使用的默认值
<bool> - “true” 或 “false”
<string> - 一个字符串 （“this is a string”
<default> - 不是特定行的一部分，如果未指定，则仅表示此字段的默认名称
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h1><p id="Emitter Components">发射器组件</p></h1>

<h2></h2>

<h2><p id="Emitter Lifetime Components">发射器生命周期组件</p></h2>

<h3></h3>

<h3><p id="Emitter Lifetime Events component">发射器生命周期事件组件</p></h3>

允许发射器上的生命周期事件触发某些事件。</br><h4></h4>
<br / ><textarea readonly="true" cols="121" rows="32">
"minecraft:emitter_lifetime_events": {
      // all events use the event names in the event section
      // all events can be an array or a string
      "creation_event": [ <string>, ...] // fires when the emitter is created
      "creation_event": <string>
      "expiration_event": [ <string>, ...] // fires when the emitter expires (does not wait for particles to expire too)
      "expiration_event": <string>

      // event timeline
      "timeline: {
        // a series of times, e.g. 0.0 or 1.0, that trigger the event
        // these get fired on every loop the emitter goes through
        // "time" is the time, e.g. one line might be:
        // "0.4": "event"
        "time": [ <string>, ... ]
        "time": <string>
      }
    }

    // travel_distance_events
    "travel_distance_events: {
        // a series of distances, e.g. 0.0 or 1.0, that trigger the event
        // these get fired when the emitter has moved by the specified input 
    // distance, e.g. one line might be:
        // "0.4": "event"
        "distance": [ <string>, ... ]
        "distance": <string>
    }

    // looping_travel_distance_events
    "looping_travel_distance_events: [
        // a series of events that occur at set intervals
    // these get fired every time the emitter has moved the specified input
    // distance from the last time it was fired.
    // An example for how to format these events would be:
        // {
        //   "distance": 1.0,
        //   "effects": [ "effect_one" ]
        // },
        // {
        //   "distance": 2.0,
        //   "effects": [ "effect_two" ]
        // }
    //
    // Note that "effect_one" and "effect_two" must be defined events within the particle_effect
    ]

}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Emitter Lifetime Expression component">发射器表达式生命周期组件</p></h3>

当激活表达式为非零时，发射器将被“打开”，当其为零时，发射器将被“关闭”。这在诸如根据实体变量驱动实体附加发射器等情况下非常有用。</br><h4></h4>
<br / ><textarea readonly="true" cols="73" rows="10">
"minecraft:emitter_lifetime_expression": {
    // When the expression is non-zero, the emitter will emit particles.
    // Evaluated every frame
    "activation_expression": <float/molang> <default:1>

    // Emitter will expire if the expression is non-zero.
    // Evaluated every frame
    "expiration_expression": <float/molang> <default:0>
}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Emitter Lifetime Looping component">发射器循环生命周期组件</p></h3>

发射器将循环，直到它被移除。</br><h4></h4>
<br / ><textarea readonly="true" cols="68" rows="11">
"minecraft:emitter_lifetime_looping": {

    // emitter will emit particles for this time per loop
    // evaluated once per particle emitter loop
    "active_time": <float/molang> <default:10>

    // emitter will pause emitting particles for this time per loop
    // evaluated once per particle emitter loop
    "sleep_time": <float/molang> <default:0>
}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Emitter Lifetime Once component">发射器单次生命周期组件</p></h3>

发射器将仅执行一次，一旦其生命周期结束或允许发射的粒子数量已全部发射，发射器将失效。</br><h4></h4>
<br / ><textarea readonly="true" cols="47" rows="6">
"minecraft:emitter_lifetime_once": {
    // how long the particles emit for
    // evaluated once
    "active_time": <float/molang> <default:10>
}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<br><br>

<h2><p id="Emitter Rate Components">发射器速率组件</p></h2>

<h3></h3>

<h3><p id="Emitter Rate Instant component">发射器瞬时速率组件</p></h3>

所有粒子会同时发射，除非发射器循环，否则不会再发射更多粒子。</br><h4></h4>
<br / ><textarea readonly="true" cols="49" rows="6">
"minecraft:emitter_rate_instant": {
    // this many particles are emitted at once
    // evaluated once per particle emitter loop
    "num_particles": <float/molang> <default:10>
}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Emitter Rate Manual component">发射器手动速率组件</p></h3>

只有当游戏本身指示发射器发射时，才会发生粒子发射。这主要用于旧版粒子特效。</br><h4></h4>
<br / ><textarea readonly="true" cols="49" rows="5">
"minecraft:emitter_rate_manual": {
    // evaluated once per particle emitted
    "max_particles": <float/molang> <default:50>
}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Emitter Rate Steady component">发射器稳定速率组件</p></h3>

粒子会以稳定或 Molang 速率随时间持续发射。</br><h4></h4>
<br / ><textarea readonly="true" cols="79" rows="10">
"minecraft:emitter_rate_steady": {
    // how often a particle is emitted, in particles/sec
    // evaluated once per particle emitted
    "spawn_rate": <float/molang> <default:1>

    // maximum number of particles that can be active at once for this emitter
    // evaluated once per particle emitter loop
    "max_particles": <float/molang> <default:50>
}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<br><br>

<h2><p id="Emitter Shape Components">发射器形状组件</p></h2>

形状决定了粒子的发射位置以及粒子的初始方向。</br><h3></h3>

<h3><p id="Emitter Disc component">发射器圆盘组件</p></h3>

该组件使用圆盘形状生成粒子，粒子可以在形状内部生成，也可以在其外边缘生成。</br><h4></h4>
<br / ><textarea readonly="true" cols="107" rows="26">
"minecraft:emitter_shape_disc": {
    // specifies the normal of the disc plane, the disc will be perpendicular to this direction
    // defaults to [ 0, 1, 0 ]
    "plane_normal": "x", // this variant has the normal in the x axis
    "plane_normal": "y", // this variant has the normal in the y axis
    "plane_normal": "z", // this variant has the normal in the z axis
    "plane_normal": [ <float/molang>, <float/molang>, <float/molang> ], // custom direction for the normal

    // specifies the offset from the emitter to emit the particles
    // evaluated once per particle emitted
    "offset": [<float/molang>, <float/molang>, <float/molang>] <default:[0, 0, 0]>

    // disc radius
    // evaluated once per particle emitted
    "radius": <float/molang> <default:1>

    // emit only from the edge of the disc
    "surface_only": <bool> <default:false>

    // specifies the direction of particles.  Defaults to "outwards"
    "direction": "inwards" // particle direction towards center of disc
    "direction": "outwards" // particle direction away from center of disc
    // evaluated once per particle emitted
    "direction": [<float/molang>, <float/molang>, <float/molang>]
}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Emitter Shape Box component">发射器立方体形状组件</p></h3>

所有粒子从发射器发出的指定大小的盒子中发射出来。</br><h4></h4>
<br / ><textarea readonly="true" cols="83" rows="22">

"minecraft:emitter_shape_box": {
    // specifies the offset from the emitter to emit the particles
    // evaluated once per particle emitted
    "offset": [<float/molang>, <float/molang>, <float/molang>] <default:[0, 0, 0]>

    // box dimensions
    // these are the half dimensions, the box is formed centered on the emitter
    // with the box extending in the 3 principal x/y/z axes by these values
    "half_dimensions": [ <float/molang>, <float/molang> <float/molang ],

    // emit only from the surface of the sphere
    "surface_only": <bool> <default:false>

    // specifies the direction of particles.  Defaults to "outwards"
    // evaluated once per particle emitted
    "direction": "inwards" // particle direction towards center of sphere
    "direction": "outwards" // particle direction away from center of sphere
    "direction": [<float/molang>, <float/molang>, <float/molang>]
}

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Emitter Shape Custom component">发射器自定义形状组件</p></h3>

所有粒子都是根据一组指定的 Molang 表达式发射的。</br><h4></h4>
<br / ><textarea readonly="true" cols="89" rows="10">
"minecraft:emitter_shape_custom": {
    // specifies the offset from the emitter to emit the particles
    // evaluated once per particle emitted
    "offset": [<float/molang>, <float/molang>, <float/molang>] <default:[0, 0, 0]>

    // specifies the direciton for the particle
    // evaluated once per particle emitted
    "direction": [<float/molang>, <float/molang>, <float/molang>] <default:[0, 0, 0]    
}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Emitter Shape Entity-AABB component">发射器实体AABB形状组件</p></h3>

所有粒子都从发射器所附加的实体的轴对齐边界框（AABB）中发射出来，如果没有实体，则从发射点发射。</br><h4></h4>
<br / ><textarea readonly="true" cols="89" rows="13">

"minecraft:emitter_shape_entity_aabb": {
    // emit only from the surface of the sphere
    "surface_only": <bool> <default:false>

    // evaluated once per particle emitted
    // defaults to outwards
    "direction": "inwards" // particle direction towards center of sphere
    "direction": "outwards" // particle direction away from center of sphere
    "direction": [<float/molang>, <float/molang>, <float/molang>] <default:[0, 0, 0]    
}

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Emitter Shape Point component">发射器点形状组件</p></h3>

所有粒子从发射器偏移的点发射出来。</br><h4></h4>
<br / ><textarea readonly="true" cols="83" rows="10">
"minecraft:emitter_shape_point": {
    // specifies the offset from the emitter to emit the particles
    // evaluated once per particle emitted
    "offset": [<float/molang>, <float/molang>, <float/molang>] <default:[0, 0, 0]>

    // specifies the direciton of particles.  
    // evaluated once per particle emitted
    "direction": [<float/molang>, <float/molang>, <float/molang>]
}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Emitter Shape Sphere component">发射器球面形状组件</p></h3>

所有粒子从发射器偏移的球体中发射出来。</br><h4></h4>
<br / ><textarea readonly="true" cols="83" rows="19">
"minecraft:emitter_shape_sphere": {
    // specifies the offset from the emitter to emit the particles
    // evaluated once per particle emitted
    "offset": [<float/molang>, <float/molang>, <float/molang>] <default:[0, 0, 0]>

    // sphere radius
    // evaluated once per particle emitted
    "radius": <float/molang> <default:1>

    // emit only from the surface of the sphere
    "surface_only": <bool> <default:false>

    // specifies the direction of particles.  Defaults to "outwards"
    "direction": "inwards" // particle direction towards center of sphere
    "direction": "outwards" // particle direction away from center of sphere
    // evaluated once per particle emitted
    "direction": [<float/molang>, <float/molang>, <float/molang>]
}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<br><br>

<h2><p id="Initial State Components">初始状态组件</p></h2>

<h3></h3>

<h3><p id="Emitter Initialization component">发射器初始化组件</p></h3>

该组件允许发射器在创建时运行一些 Molang，主要用于填充后续会使用的任何 Molang 变量。</br><h4></h4>
<br / ><textarea readonly="true" cols="75" rows="7">

"minecraft:emitter_initialization": {
  "creation_expression": <molang>, // this is run once at emitter startup
  "per_update_expression": <molang> // this is run once per emitter update
}

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Emitter Local Space component">发射器局部空间组件</p></h3>

此组件指定发射器的参考系。仅当发射器附加到实体时适用。当 'position' 为 true 时，粒子将在实体空间中模拟，否则将在世界空间中模拟。Rotation 的工作方式与 rotation 相同。两者的默认值均为 false，这将使粒子相对于发射器发射，然后独立于发射器进行模拟。请注意，rotation = true 和 position = false 是无效选项。Velocity 将发射器的速度添加到初始粒子速度中。</br><h4></h4>
<br / ><textarea readonly="true" cols="35" rows="6">
"minecraft:emitter_local_space": {
    "position": <bool>
    "rotation": <bool>
    "velocity": <bool>
}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<br><br>

<br><br>

<h1><p id="Particle Components">粒子组件</p></h1>

<h2></h2>

<h2><p id="Particle Appearance Components">粒子外观组件</p></h2>

<h3></h3>

<h3><p id="Particle Appearance Billboard component">粒子公告板外观组件</p></h3>

该组件告诉粒子系统将粒子渲染为公告板，即世界中面向特定方向的矩形。</br><h4></h4>
<br / ><textarea readonly="true" cols="178" rows="32">
"minecraft:particle_appearance_billboard": {
    // specifies the x/y size of the billboard
    // evaluated every frame
    "size": [<float/molang>, <float/molang>],

    // used to orient the billboard.  Options are:
    // "rotate_xyz" - aligned to the camera, perpendicular to the view axis
    // "rotate_y" - aligned to camera, but rotating around world y axis
    // "lookat_xyz" - aimed at the camera, biased towards world y up
    // "lookat_y" - aimed at the camera, but rotating around world y axis
    // "direction_x" - unrotated particle x axis is along the direction vector, unrotated y axis attempts to aim upwards
    // "direction_y" - unrotated particle y axis is along the direction vector, unrotated x axis attempts to aim upwards
    // "direction_z" - billboard face is along the direction vector, unrotated y axis attempts to aim upwards
  // emitter_transform_xy, // orient the particles to match the emitter's transform (the billboard plane will match the transform's xy plane).
  // emitter_transform_xz, // orient the particles to match the emitter's transform (the billboard plane will match the transform's xz plane).
  // emitter_transform_yz, // orient the particles to match the emitter's transform (the billboard plane will match the transform's yz plane).
  
    //"face_camera_mode": <string>

    // Specifies how to calculate the direction of a particle, this will be used by facing modes that require a direction as input (for instance: lookat_direction and direction)
    // Options are:
    // "derive_from_velocity" - The direction matches the direction of the velocity.
    // "custom_direction" - The direction is specified in the json definition using a vector of floats or molang expressions.
    // If the direction subsection is not defined, the default will be "derive_from_velocity" mode with a "min_speed_threshold" of 0.01.
    "direction": {
        "mode": "derive_from_velocity" or "custom_direction",
        "min_speed_threshold": <float> // only used in "derive_from_velocity" mode. The direction is set if the speed of the particle is above the threshold. The default is 0.01
        "custom_direction": [ <float/molang>, <float/molang>, <float/molang> ], // only used in "custom_direction" mode. Specifies the direction vector
    }

    // specifies the UVs for the particle.  
    "uv": {
        // specifies the assumed texture width/height
        // defaults to 1
        // when set to 1, UV's work just like normalized UV's
        // when set to the texture width/height, this works like texels
        "texturewidth": <int>,
        "textureheight": <int>,

        // Assuming the specified texture width and height, use these 
        // uv coordinates.  
        // evaluated every frame
        "uv": [<float/molang>, <float/molang>],
        "uv_size": [<float/molang>, <float/molang>],

        // alternate way via specifying a flipbook animation
        // a flipbook animation uses pieces of the texture to animate, by stepping over time from one 
        // "frame" to another
        "flipbook": {
            "base_UV": [ <float/molang>, <float/molang> ], // upper-left corner of starting UV patch
            "size_UV": [ <float>, <float> ], // size of UV patch
            "step_UV": [ <float>, <float> ], // how far to move the UV patch each frame
            "frames_per_second": <float>, // default frames per second
            "max_frame": <float/molang>, // maximum frame number, with first frame being frame 1
            "stretch_to_lifetime": <bool>, // optional, adjust fps to match lifetime of particle. default=false
            "loop":  <bool> // optional, makes the animation loop when it reaches the end? default=false
        }
    }
}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Particle Appearance Lighting">粒子光照外观</p></h3>

当存在此组件时，粒子将根据游戏中的局部光照条件进行着色。</br><h4></h4>
<br / ><textarea readonly="true" cols="45" rows="2">
"minecraft:particle_appearance_lighting": {}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Particle Appearance Tinting component">粒子染色外外观组件</p></h3>

该组件控制粒子的颜色着色：</br><h4></h4>
<br / ><textarea readonly="true" cols="75" rows="32">

// color fields are special, they can be either an RGB, or a "#RRGGBB"
// field (or RGBA or "AARRGGBB").  If RGB(A), the channels are
// from 0 to 1.  If the string "#AARRGGBB", then the values are
// hex from 00 to ff.
//
// this pseudo-type will be denoted by <color>
"minecraft:particle_appearance_tinting": {
    // interpolation based color
    "color": {
        // an array of colors
        // there are two ways to specify the array of colors
        // the first method is to just have an array of colors
        // these will be interpreted to be equally spaced, with the entire
        // range going from 0 to 1
        //
        // the second option is to specify a value/color pair list
        // this will cause the colors to appear when their specified value
        // occurs in the interpolant, and interpolated in between.  Note
        // that this will be sorted
        "gradient": [ <color>, <color>, ...],
        "gradient": {
        <float>: <color>,
        <float>: <color>,
        ...
        }
        "interpolant": <float/molang> // hint: use a curve here!
    }

    // directly set the color
    "color": <color>
    // examples of direct color field:
    "color": "#ff0000"
    "color": [1, 0, 0]
},

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<br><br>

<h2><p id="Particle Initial State Components">粒子初始状态组件</p></h2>

<h3></h3>

<h3><p id="Particle Initial Speed component">粒子初始速度组件</p></h3>

根据发射器形状指定的方向，使粒子以指定的速度开始运动。</br><h4></h4>
<br / ><textarea readonly="true" cols="85" rows="7">

// evaluated once
"minecraft:particle_initial_speed": <float/molang> <default:0>

"minecraft:particle_initial_speed" [<float/molang>, <float/molang>, <float/molang>],

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Particle Initial State component">粒子初始状态组件</p></h3>

使粒子以指定的朝向和旋转速率开始运动。</br><h4></h4>
<br / ><textarea readonly="true" cols="49" rows="10">
"minecraft:particle_initial_spin": {
    // specifies the initial rotation in degrees
    // evaluated once
    "rotation": <float/molang> <default:0>

    // specifies the spin rate in degrees/second
    // evaluated once
    "rotation_rate": <float/molang> <default:0>
}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<br><br>

<h2><p id="Particle Lifetime Components">粒子生命周期组件</p></h2>

<h3></h3>

<h3><p id="Particle Expire If In Blocks component">粒子若于方块中则过期组件</p></h3>

当粒子处于列表中指定类型的方块内时，粒子会失效。注意：此组件可以与 particle_lifetime_expression 组件同时存在。</br><h4></h4>
<br / ><textarea readonly="true" cols="70" rows="9">
"minecraft:particle_expire_if_in_blocks" [
    // minecraft block names, e.g. 'minecraft:water', 'minecraft:air'
    // these are typically the same name as in the /setblock command
    // except for the minecraft: prefix
    "blockname1",
    "blockname2", 
    ...
],
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Particle Expire If Not In Blocks component">粒子若不于方块中则过期组件</p></h3>

当粒子处于不在列表中的方块类型内时，粒子会失效。注意：此组件可以与 particle_lifetime_expression 组件同时存在。</br><h4></h4>
<br / ><textarea readonly="true" cols="70" rows="9">
"minecraft:particle_expire_if_not_in_blocks" [
    // minecraft block names, e.g. 'minecraft:water', 'minecraft:air'
    // these are typically the same name as in the /setblock command
    // except for the minecraft: prefix
    "blockname1",
    "blockname2", 
    ...
],
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Particle Lifetime Events component">粒子生命周期事件组件</p></h3>

该组件可以根据各种生命周期事件触发事件。</br><h4></h4>
<br / ><textarea readonly="true" cols="121" rows="18">
"minecraft:particle_lifetime_events": {
      // all events use the event names in the event section
      // all events can be either an array or a string
      "creation_event": [<string>, ...] // fires when the particle is created
      "creation_event": <string> 
      "expiration_event": [<string>, ...] // fires when the particle expires (does not wait for particles to expire too)
      "expiration_event": <string>,

      // event timeline
      "timeline": {
        // a series of times, e.g. 0.0 or 1.0, that trigger the event
        // "time" is the time, e.g. one line might be:
        // "0.4": "event"
        "time": [<string>", ...]
        "time": <string>
      }
}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Particle Lifetime Expression component">粒子表达式生命周期组件</p></h3>

标准生命周期组件。这些表达式控制粒子的生命周期。</br><h4></h4>
<br / ><textarea readonly="true" cols="70" rows="12">
"minecraft:particle_lifetime_expression": {
    // this expression makes the particle expire when true (non-zero)
    // The float/expr is evaluated once per particle
    // evaluated every frame
    "expiration_expression": <float/molang> <default:0>
 
  // alternate way to express lifetime
    // particle will expire after this much time
    // evaluated once
    "max_lifetime": <float/molang>
}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Particle Lifetime Kill-Plane component">粒子终止平面生命周期组件</p></h3>

穿过该平面的粒子会失效。该平面相对于发射器，但在世界空间中定向。四个参数是平面方程的四个常规元素。</br><h4></h4>
<br / ><textarea readonly="true" cols="72" rows="5">
// A*x + B*y + C*z + D = 0
// with the parameters being [ A, B, C, D ]
"minecraft:particle_kill_plane": [ <float>, <float>, <float>, <float> ]

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<br><br>

<h2><p id="Particle Motion Components">粒子运动组件</p></h2>

<h3></h3>

<h3><p id="Particle Motion Collision component">粒子碰撞运动组件</p></h3>

该组件启用粒子与地形之间的碰撞。Minecraft 中的碰撞检测包括检测交叉点，将粒子移动到附近不交叉的点（如果可能），并将方向设置为不朝向碰撞方向（通常与碰撞表面垂直）。请注意，如果不存在此组件，则不会发生碰撞。</br><h4></h4>
<br / ><textarea readonly="true" cols="95" rows="32">

"minecraft:particle_motion_collision": {
    // enables collision when true/non-zero.
    // evaluated every frame
    "enabled": <bool/molang> <default:true>

    // alters the speed of the particle when it has collided
    // useful for emulating friction/drag when colliding, e.g a particle
    // that hits the ground would slow to a stop.
    // This drag slows down the particle by this amount in blocks/sec
    // when in contact
    "collision_drag": <float>

    // used for bouncing/not-bouncing
    // Set to 0.0 to not bounce, 1.0 to bounce back up to original hight
    // and in-between to lose speed after bouncing.  Set to >1.0 to gain energy on each bounce
    "coefficient_of_restitution": <float>

    // used to minimize interpenetration of particles with the environment
    // note that this must be less than or equal to 1/2 block
    "collision_radius": <float>

    // triggers expiration on contact if true
    "expire_on_contact": <bool>

    // triggers an event
    // array of individual events
    "events": [
        {
          // triggers the specified event if the conditions are met
          "event": <string>
          // optional minimum speed for event triggering
          "min_speed": <float> // default/minimum is 2 blocks/sec
        },
    ],
    "events": { // can be an individual event as well
        // triggers the specified event if the conditions are met
        "event": <string>
        // optional minimum speed for event triggering
        "min_speed": <float> // default/minimum is 2 blocks/sec
    }
}

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Particle Motion Dynamic component">粒子动力学运动组件</p></h3>

该组件指定粒子的动态属性，从模拟的角度来看，哪些力作用于粒子？这些动态属性会改变粒子的速度，速度是粒子方向和速度的组合。粒子的方向始终与粒子的速度方向一致。</br><h4></h4>
<br / ><textarea readonly="true" cols="85" rows="32">
"minecraft:particle_motion_dynamic": {
    // the linear acceleration applied to the particle, defaults to [0, 0, 0].
    // Units are blocks/sec/sec
    // An example would be gravity which is [0, -9.8, 0]
    // evaluated every frame
    "linear_acceleration": [<float/molang>, <float/molang>, <float/molang>],

    // using the equation:
    // acceleration = -linear_drag_coefficient*velocity
    // where velocity is the current direction times speed
    // Think of this as air-drag.  The higher the value, the more drag
    // evaluated every frame
    "linear_drag_coefficient": <float/molang> <default:0>

    // acceleration applies to the rotation speed of the particle
    // think of a disc spinning up or a smoke puff that starts rotating
    // but slows down over time
    // evaluated every frame
    // acceleration is in degrees/sec/sec
    "rotation_acceleration" <float/molang> <default:0>

    // drag applied to retard rotation
    // equation is rotation_acceleration += -rotation_rate*rotation_drag_coefficient
    // useful to slow a rotation, or to limit the rotation acceleration
    // Think of a disc that speeds up (acceleration) 
    // but reaches a terminal speed (drag)
    // Another use is if you have a particle growing in size, having
    // the rotation slow down due to drag can add "weight" to the particle's
    // motion
    "rotation_drag_coefficient" <float/molang> <default:0>
}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h3><p id="Particle Motion Parametric component">粒子参数化运动组件</p></h3>

该组件直接控制粒子。请注意，此组件不适用于手动发射的粒子，也不适用于不在局部空间中的基于实体的粒子发射器。</br><h4></h4>
<br / ><textarea readonly="true" cols="72" rows="19">
"minecraft:particle_motion_parametric": {
    // directly set the position relative to the emitter. 
    // E.g. a spiral might be:
    // "relative_position": ["Math.cos(Params.LifeTime)", 1.0, 
    //                       "Math.sin(Params.Lifetime)"]
    // defaults to [0, 0, 0]
    // evaluated every frame
    "relative_position": [<float/molang> <float/molang> <float/molang>]

    // directly set the 3d direction of the particle
    // doesn't affect direction if not specified
    // evaluated every frame
    "direction": [<float/molang> <float/molang> <float/molang]

    // directly set the rotation of the particle
    // evaluated every frame
    "rotation": <float/molang> <default:0>
}}
</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<br><br>

<br><br>

<br><br>

<h1><p id="Curves">曲线</p></h1>

曲线是插值，输入范围为0到1，输出基于曲线本身。曲线的结果是一个与曲线同名的 Molang 变量，可以在组件的 Molang 中引用。对于每个粒子的每一帧渲染，都会评估曲线，并将结果存储在一个与曲线同名的 Molang 变量中。</br><h2></h2>
<br / ><textarea readonly="true" cols="120" rows="32">

    "curves": {
      // "molangvar" is the Molang variable to be used later in Molang expressions
      // for example "variable.mycurve" here would make the result of the curve
      // available in Molang as "variable.mycurve".  Note that all variables must begin with "variable."
      "molangvar": {
        // type can be "linear", "bezier", "bezier_chain", or "catmull_rom"
        // "linear" is a series of nodes, equally spaced between 0 and 1 (after applying input/horizontal_range)
        // "bezier" is a 4-node bezier spline, with the first and last point being the values at 0 and 1
        //   and the middle two points forming the slope lines at 0.33 for the first point and 0.66 for the second
        // "catmull_rom" is a series of curves which pass through all but the last/first node.  The first/last nodes
        // are used to form the slope of the second/second-last points respectively.  All points are evenly spaced.
        // "bezier_chain" is a chain of bezier splines.  See below for the node configuration.  A series of points are
        //   specified, along with their corresponding slopes, and each segment will use it's pair of points and
        //   slopes to form a bezier spline.  Each point other than first/last is shared between it's pair of 
        //   spline segments.
        "type": type, 

        // control nodes for curve.  These are assumed to be equally
        // spaced, e.g. first node is at input value 0, second at 0.25, etc
        // this notation works only for linear, bezier, and catmull_rom
        "nodes": [<float/molang>, <float/molang>, <float/molang>, <float/molang>],

        // control nodes for bezier_chain
        // the nodes will be sorted prior to parsing, so if you declare nodes 0.3, 0.6, 0.5, they will be
        // re-ordered to 0.3, 0.5, 0.6
        "nodes": {
            // the key values map to the "input" field
            "0.3": {
                "value": "5", // the output of the curve
                "left_value": "2", // when curve comes from the left of the node, what point does it use?
                "right_value": "3", // when curve comes from the right side of the node, what point does it use?
                "slope": "3", // the slope of the node, both sides
                "left_slope: "0.4", // the left slope of the node
                "right_slope": "2", // the right slope of the node
            },
            ... // more nodes
        },

        // what is the input value to use
    // for example, "variable.particle_age/variable.particle_lifetime would result in an input from 0 to 1 over
    // the lifetime of the particle, while variable.particle_age would have input of how old the particle is in seconds
        "input": <float/molang>,

        // what is the range the input is mapped onto
        // between 0 and this value
    // note: this field is deprecated and optional (default: 1.0)
    // note: this field is ignored for bezier_chain
        "horizontal_range": <float/molang>
      }
    }

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h1><p id="Events">事件</p></h1>

事件可以在.json文件的其他地方触发，并启动新的粒子和声音效果。</br></br>粒子特效有不同的类型。如果类型是“emitter”，这将在事件的世界位置创建一个“effect”类型的发射器，以一种发射后就不管的方式。 “emitter_bound” 的工作方式类似，只是如果生成发射器绑定到一个活动对象/定位器，新的发射器将绑定到相同的活动对象/定位器。如果类型是“particle”，那么事件将在事件位置的手动发射器上发射一个粒子，如果发射器不存在，则创建它（确保使用“minecraft:emitter_rate_manual”作为生成的发射器效果）。 “particle_with_velocity” 将与“particle”做同样的事情，只是新粒子将继承生成粒子的速度。</br></br>声音效果指定了当事件触发时要播放的具体“级别声音事件”。</br></br>事件本身由一个可选的节点树和/或一个实际事件组成。当指定“sequence”时，该数组将按顺序执行，当事件触发时，每个元素都将执行。使用“random”时，将根据权重从数组中选择一个元素。</br><h2></h2>
<br / ><textarea readonly="true" cols="117" rows="32">

  // events block:
  "events": {
    "event_name1",
    "event_name2",
    ...
  }

  // structure of an event, note that nesting can be any combination of "sequence", or "randomize"
      "event_name": {
        "sequence": [
          { /*this node executes first*/ },
          { /*this node executes second*/ },
          { /* etc */},
          { 
            "sequence": [
              { 
                // nested nodes
              },
              ...
            ]
          },
          { 
            "randomize": [
              {
                "weight": <float>
                /* data for this option, including other sequences/randoms */
              },
              ...
            ]
          }
        ]
      },

      // Fields for a particlar event.  Note that any of the above nodes can have events inserted into their blocks.
      "event_subpart": {
          "particle_effect": {
            // identifier of the effect
            "effect": <string>,
            // "emitter", "emitter_bound", "particle" or "particle_with_velocity"
            "type": <string>,
            // this Molang is run on the emitter for this event once this
            // event fires
            // NOTE: this will not have access to the event
            // triggering emitter's Molang data
            "pre_effect_expression": <string>,
          },
          "sound_effect": {
            // name of the level sound event
            "event_name": <string>
          },
          // Runs this Molang expression on the event-firing emitter
          "expression": <string>,
          // for debugging, this will log a message, along with the firing effect's name and event position
          // the log message will show up in the content logger
          "log": <string>
      }

    // simple example:
    "events": {
        "event_name1": {
            "particle_effect": {
                "effect": "a_particle_effect",
                "type": "emitter"
            }
        }
    }

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h1><p id="Examples">示例</p></h1>

<h1><p id="Bouncing Bubbles">弹跳气泡</p></h1>

这种粒子特效会生成许多四处弹跳的气泡。</br><h2></h2>
<br / ><textarea readonly="true" cols="100" rows="32">

{
  "format_version": "1.10.0",
  "particle_effect": {
    "description": {
      "identifier": "minecraft:test_bounce",
      "basic_render_parameters": {
        "material": "particles_alpha",
        "texture": "textures/particle/particles"
      }
    },  
    "components": {
      "minecraft:emitter_rate_instant": {
        "num_particles": 100
      },
      "minecraft:emitter_lifetime_once": {
        "active_time": 2
      },
      "minecraft:emitter_shape_sphere": {
        "offset": [ "Math.random(-0.5, 0.5)", "Math.random(-0.5, 0.5)", "Math.random(-0.5, 0.5)" ],
        "direction": "outwards",
        "radius": 1
      },
      "minecraft:particle_initial_speed": 5.0,
      "minecraft:particle_initial_spin": {
        "rotation": "Math.random(0, 360)",
        "rotation_rate": 0
      },
      "minecraft:particle_lifetime_expression": {
        "max_lifetime": "5"
      },
      "minecraft:particle_motion_dynamic": {
        "linear_acceleration": [ 0, -9.8, 0 ]
      },
      "minecraft:particle_motion_collision": {
        "coefficient_of_restitution": 0.5,
        "collision_drag": 4,
        "collision_radius": 0.1
      },
      "minecraft:particle_appearance_billboard": {
        "size": [ "0.1", "0.1" ],
        "facing_camera_mode": "lookat_xyz",
        "uv": {
          "texture_width": 128,
          "texture_height": 128,
          "uv": [ 0, 16 ],
          "uv_size": [ 8, 8 ]
        }
      },
      "minecraft:particle_appearance_lighting": {}
    }
  }
}

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h1><p id="Flame particle">火焰粒子</p></h1>

这种粒子是出现在火把和熔炉上的小火焰，用来表示火。它是一个简单的粒子，由一个静止的火焰组成，有一些变化。注意使用 Molang 来创建粒子行为的变化。</br></br>此外，在公告板组件的UV部分使用 texturewidth/height，允许通过 texels 引用 UV：</br><h2></h2>
<br / ><textarea readonly="true" cols="81" rows="32">

{
  "format_version": "1.10.0",
  "particle_effect": {
    "description": {
      "identifier": "minecraft:basic_flame_particle",
      "basic_render_parameters": {
        "material": "particles_alpha",
        "texture": "textures/particle/particles"
      }
    },
    "components": {
      "minecraft:emitter_rate_instant": {
        "num_particles": 1
      },
      "minecraft:emitter_lifetime_expression": {
        "activation_expression": 1,
        "expiration_expression": 0
      },
      "minecraft:emitter_shape_sphere": {
        "radius": 0.025,
        "direction": [ 0, 0, 0 ]
      },
      "minecraft:particle_lifetime_expression": {
        "max_lifetime": "Math.random(0.6, 2.0)"
      },
      "minecraft:particle_appearance_billboard": {
        "size": [
          "(0.1 + variable.ParticleRandom1*0.1) - (0.1 * variable.ParticleAge)",
          "(0.1 + variable.ParticleRandom1*0.1) - (0.1 * variable.ParticleAge)"
        ],
        "facing_camera_mode": "lookat_xyz",
        "uv": {
          "texture_width": 128,
          "texture_height": 128,
          "uv": [ 0, 24 ],
          "uv_size": [ 8, 8 ]
        }
      }
    }
  }
}

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h1><p id="Mob Flame effect">生物火焰效果</p></h1>

生物火焰效果是烈焰人在蓄力投掷火球时使用的。这是一种随着时间上升的动画翻页火焰效果。</br></br>与早期的粒子不同，这是一个常规发射器。它与一个实体绑定，因此使用实体轴对齐边界框（entity_aabb）的形状，因为我们希望火焰出现在烈焰人全身。由于该效果与充能状态相关，因此使用激活表达式，与实体变量EntityFlag::CHARGED绑定。这使得火焰在烈焰人充能时出现，而在未充能时消失。</br></br>在这种情况下，我们使用纹理宽度/高度来使纹素（texel）“分辨率”为动画的一帧，从而允许帧的推进仅为1。</br><h2></h2>
<br / ><textarea readonly="true" cols="63" rows="32">

{
  "format_version": "1.10.0",
  "particle_effect": {
    "description": {
      "identifier": "minecraft:mobflame_emitter",
      "basic_render_parameters": {
        "material": "particles_alpha",
        "texture": "textures/flame_atlas"
      }
    },
    "components": {
      "minecraft:emitter_local_space": {
        "position": true,
        "rotation": true
      },
      "minecraft:emitter_rate_steady": {
        "spawn_rate": "Math.random(15, 25)",
        "max_particles": 50
      },
      "minecraft:emitter_lifetime_expression": {
        "activation_expression": 1,
        "expiration_expression": 0
      },
      "minecraft:emitter_shape_entity_aabb": {
        "direction": [ 0, 1, 0 ]
      },
      "minecraft:particle_initial_speed": "Math.random(0, 1)",
      "minecraft:particle_lifetime_expression": {
        "max_lifetime": 1.25
      },
      "minecraft:particle_motion_dynamic": {
        "linear_acceleration": [ 0, 1.0, 0 ],
        "linear_drag_coefficient": 0.0
      },
      "minecraft:particle_appearance_billboard": {
        "size": [ 0.5, 0.5 ],
        "facing_camera_mode": "lookat_xyz",
        "uv": {
          "texture_width": 1,
          "texture_height": 32,
          "flipbook": {
            "base_UV": [ 0, 0 ],
            "size_UV": [ 1, 1 ],
            "step_UV": [ 0, 1 ],
            "frames_per_second": 32,
            "max_frame": 32,
            "stretch_to_lifetime": true,
            "loop": false
          }
        }
      }
    }
  }
}

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h1><p id="Smoke particle">烟雾粒子</p></h1>

这种粒子是通用的烟雾团。它出现在火把、熔炉、烈焰人等上面。它是一个简单的粒子，具有向上的运动，由向上的加速度和阻力共同作用。</br></br>这种粒子与火焰粒子的主要区别在于翻页纹理动画。具体细节见下面的粒子，但该效果使用了公告板外观组件的翻页子部分，以驱动uv坐标随时间从一帧到另一帧。</br></br>此外，在广告牌组件的UV部分使用纹理宽度/高度，允许通过 texel 引用翻页的UV坐标。</br><h2></h2>
<br / ><textarea readonly="true" cols="121" rows="32">

{
  "format_version": "1.10.0",
  "particle_effect": {
    "description": {
      "identifier": "minecraft:basic_smoke_particle",
      "basic_render_parameters": {
        "material": "particles_alpha",
        "texture": "textures/particle/particles"
      }
    },
    "components": {
      "minecraft:emitter_rate_instant": {
        "num_particles": 1
      },
      "minecraft:emitter_lifetime_expression": {
        "activation_expression": 1,
        "expiration_expression": 0
      },
      "minecraft:emitter_shape_custom": {
        "offset": [ 0, 0, 0 ],
        "direction": [ "Math.random(-0.1, 0.1)", 1.0, "Math.random(-0.1, 0.1)" ]
      },
      "minecraft:particle_initial_speed": 1.0,
      "minecraft:particle_lifetime_expression": {
        "max_lifetime": "Math.random(0.4, 1.4)"
      },
      "minecraft:particle_motion_dynamic": {
        "linear_acceleration": [ 0, 0.4, 0 ]
      },
      "minecraft:particle_appearance_billboard": {
        "size": [ 0.1, 0.1 ],
        "facing_camera_mode": "lookat_xyz",
        "uv": {
          "texture_width": 128,
          "texture_height": 128,
          "flipbook": {
            "base_UV": [ 56, 0 ],
            "size_UV": [ 8, 8 ],
            "step_UV": [ -8, 0 ],
            "frames_per_second": 8,
            "max_frame": 8,
            "stretch_to_lifetime": true,
            "loop": false
          }
        }
      },
      "minecraft:particle_appearance_tinting": {
        "color": [ "variable.ParticleRandom1*0.5", "variable.ParticleRandom1*0.5", "variable.ParticleRandom1*0.5", 1.0 ]
      },
      "minecraft:particle_appearance_lighting": {}
    }
  }
}

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<br><br>

<h1><p id="Materials">材质</p></h1>

有几种材质选项可用于决定粒子如何处理透明度和颜色混合</br><h2></h2>

<table border="1" style="width:100%; border-style:solid; border-collapse:collapse; border-width:3;">
<tr> <th style="border-style:solid; border-width:3;">名称</th> <th style="border-style:solid; border-width:3;">描述</th> </tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">particles_add</td>
<td style="border-style:solid; border-width:3; padding:7px">启用彩色像素的颜色混合与透明度效果，采用叠加混合模式 (additive blend)。</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">particles_alpha </td>
<td style="border-style:solid; border-width:3; padding:7px">alpha 值为 0 的像素将完全透明，彩色像素始终不透明</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">particles_blend</td>
<td style="border-style:solid; border-width:3; padding:7px">启用彩色像素的颜色混合与透明度效果，采用标准混合模式(normal blend)。</br></td>
</tr>
</table>
<a href="#Index">返回顶部</a><br><br>

<br><br>

<h1><p id="Molang integration">Molang集成</p></h1>

在适用的地方，任何字段都可以使用 Molang 表达式。Molang 表达式是字符串，其定义详见 Molang 文档。粒子系统使用了一些特殊的 Molang 变量，这些变量可供粒子 Molang 表达式使用。此外，还可以通过多种方式设置自定义 Molang 参数，并在特效的 Molang 表达式中使用它们。</br><h2></h2>

<table border="1" style="width:100%; border-style:solid; border-collapse:collapse; border-width:3;">
<tr> <th style="border-style:solid; border-width:3;">名称</th> <th style="border-style:solid; border-width:3;">描述</th> </tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">variable.emitter_age</td>
<td style="border-style:solid; border-width:3; padding:7px">发射器当前循环开始以来的持续时间</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">variable.emitter_lifetime</td>
<td style="border-style:solid; border-width:3; padding:7px">发射器当前循环的持续时间</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">variable.emitter_random_1</td>
<td style="border-style:solid; border-width:3; padding:7px">发射器当前循环中从0.0到1.0的随机值，且在当前循环中保持不变</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">variable.emitter_random_2</td>
<td style="border-style:solid; border-width:3; padding:7px">发射器当前循环中另一个从0.0到1.0的随机值，且在当前循环中保持不变</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">variable.emitter_random_3</td>
<td style="border-style:solid; border-width:3; padding:7px">发射器当前循环中的第三个从0.0到1.0的随机值，且在当前循环中保持不变</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">variable.emitter_random_4</td>
<td style="border-style:solid; border-width:3; padding:7px">发射器当前循环中的第四个从0.0到1.0的随机值，且在当前循环中保持不变</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">variable.entity_scale</td>
<td style="border-style:solid; border-width:3; padding:7px">当效果附加到实体上时，这个值是实体的缩放比例</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">variable.particle_age</td>
<td style="border-style:solid; border-width:3; padding:7px">粒子已经存在的时间</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">variable.particle_lifetime</td>
<td style="border-style:solid; border-width:3; padding:7px">粒子的生命周期</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">variable.particle_random_1</td>
<td style="border-style:solid; border-width:3; padding:7px">粒子生命周期内从0.0到1.0的随机值，且在粒子生命周期内保持不变</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">variable.particle_random_2</td>
<td style="border-style:solid; border-width:3; padding:7px">粒子生命周期内的另一个从0.0到1.0的随机值，且在粒子生命周期内保持不变</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">variable.particle_random_3</td>
<td style="border-style:solid; border-width:3; padding:7px">粒子生命周期内的第三个从0.0到1.0的随机值，且在粒子生命周期内保持不变</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">variable.particle_random_4</td>
<td style="border-style:solid; border-width:3; padding:7px">粒子生命周期内的第四个从0.0到1.0的随机值，且在粒子生命周期内保持不变</br></td>
</tr>
</table>
<a href="#Index">返回顶部</a><br><br>

<br><br>

<h1><p id="Namespacing">命名空间</p></h1>

所有粒子特效都应进行命名空间划分（在其名称中）。</br></br>命名空间划分涉及在效果标签上添加“name:”前缀。</br></br>常规的 Minecraft 将使用“minecraft:”前缀。请参阅示例中的示例名称。</br><a href="#Index">返回顶部</a><br><br>

<h1><p id="Particles Entity Integration">粒子的实体集成</p></h1>

</br>在基岩引擎中发射粒子的主要用途之一是与实体相关的粒子，例如生物。例如，烈焰人在攻击序列中火焰燃烧，或者唤魔者在召唤恼鬼时的法术效果。目标是允许绑定和管理附加到实体的粒子特效。</br></br>通过 .json 管理与实体相关的粒子时，以下概念非常重要：</br>- 效果列表。这些位于实体的 .json 资源定义中，与纹理等一起。这些列出了实体可用的效果，包括效果的内部实体名称和要播放的关联效果。</br>- 定位器。这些位于几何文件中，指定了几何中的一个位置。这些定位器可以与骨骼关联，因此会随着骨骼的动画而移动。</br>- 通过 动画控制器（Animation Controller） 的状态机逻辑，可以实现对粒子特效的灵活控制，包括 一次性触发（Fire-and-Forget） 和 持续播放（Sustained） 两种模式</br>- 动画时间轴粒子管理。作为实体的动画.json的一部分，可以在动画播放时设置一个时间轴，在指定的时间触发粒子特效。请注意，不需要实际的物理动画，只需要动画的.json结构。</br></br>附加到实体的粒子与这些实体密切相关。如果实体不再存在，粒子特效也会停止。发射器可跟随实体整体移动，或精准追踪实体上的特定定位点（locator）。</br><h1><p id="Animation Controller effects">动画控制器效果</p></h1>

</br>动画控制器可为其状态指定特效事件。这允许在进入状态时启动一系列粒子特效，并在离开该状态时自动终止这些效果。对于不会自行结束（或在状态转换前未能结束）的粒子特效，系统将在退出状态时强制终止它们。</br></br>架构为：</br>"particle_effects": [</br>    // 效果事件的数组</br>]</br>使用数组语法可以在进入状态时触发多个特效。</br></br>以烈焰人的火焰升腾效果为例：其动画控制器包含 "default"（默认）和 "flaming"（燃烧）两种状态，通过检测实体标记 "query.is_charged"实现状态切换。当进入 "flaming" 状态时，系统将启动 "charged_flames" 粒子特效（无需定位器或 Molang 初始化表达式），并在退出该状态时自动终止该特效。</br><h2></h2>
<br / ><textarea readonly="true" cols="47" rows="32">

{
  "format_version": "1.8.0",
  "animation_controllers": {

    ...

    "controller.animation.blaze.flame": {
      "states": {
        "default": {
          "transitions": [
            { "flaming": "query.is_charged" }
          ]
        },
        "flaming": {
          "particle_effects": [
            {
              "effect": "charged_flames"
            }
          ],
          "transitions": [
            { "default": "!query.is_charged" }
          ]
        }
      }
    },

    ...

  }
}

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h1><p id="Animation Controller effects (continued)">动画控制器效果（持续）</p></h1>

</br>另一个例子是唤魔者的法术效果。这使得唤魔者启动两个“spell”效果，使用左手和右手的定位器。法术效果本身是连续的，因此发射器会持续发射粒子，直到唤魔者不再施法。</br><h2></h2>
<br / ><textarea readonly="true" cols="47" rows="32">

{
  "format_version": "1.8.0",
  "animation_controllers": {
    "controller.animation.evoker.general": {
      "states": {
        "default": {
            ...
          "transitions": [
            { "casting": "query.is_casting" }
          ]
        },
        "casting": {
            ...
          "particle_effects": [
            {
              "effect": "spell",
              "locator": "left_hand"
            },
            {
              "effect": "spell",
              "locator": "right_hand"
          }
          ],
          "transitions": [
            { "default": "!query.is_casting" }
          ]
        }
      }
    }
  }
}

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h1><p id="Animation Timeline effects">动画时间轴效果</p></h1>

动画同样可以触发粒子特效。这类特效采用"一次性触发"机制，它们被绑定到时间轴上——当动画播放到特定时间点时，就会触发对应的特效。</br><h2></h2>
<br / ><textarea readonly="true" cols="34" rows="14">

"particle_effects": {
    "time1" : [
        // 效果事件的数组
    ],
    "time2" : [
        // 效果事件的数组
    ],
    "time3" : {
      // 单个效果
    }
}

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h1><p id="Animation Timeline effects (continued)">动画时间轴效果（持续）</p></h1>

time1/time2/等是数值时间点，例如“0.0”。</br></br>在这个例子中，当猫坐下3秒后，将生成一团烟雾粒子效果：</br><h2></h2>
<br / ><textarea readonly="true" cols="35" rows="25">

{
  "format_version": "1.8.0",
  "animations": {
    ...
    "animation.cat.sit": {
      "loop": true,
      "animation_length": 5.0,
      "bones": {
          // bone animation stuff
       },
      "particle_effects": {
        "3.0": [
          {
            "effect": "smoke_puff"
          }
        ]
      }
    },
    ...
    }
  }
}

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h1><p id="Effect Event">效果事件</p></h1>

</br>实体中的粒子特效事件具有以下属性：</br>- "effect" 是在实体的资源定义 .json（粒子特效列表）中指定的特效名称，用于确定要启动/播放的具体粒子特效。</br>- "locator"（定位器）为可选参数，需对应资源定义文件中同名定位器。指定后，粒子发射器将随实体动画移动并同步该定位器的位置与朝向。若未指定，特效将在实体原点位置生成。</br>- "pre_effect_script"（预执行脚本）是可选参数，该参数为在发射器启动时运行的 Molang 表达式。它可用于初始化 Molang 变量（如"粒子颜色"），这些变量后续可在粒子特效 .json 文件中直接引用。</br><h2></h2>
<br / ><textarea readonly="true" cols="43" rows="8">

{
    "effect": "internal_name",
    "locator": "locator_name", // 自选
    "pre_effect_script" // 自选
}

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h1><p id="Effect List">效果列表</p></h1>

特效列表（effect list） 是内部特效名称与实际粒子特效绑定的映射列表。这是为实体添加粒子特效的通用形式，其中包含一系列简称与实际特效的对应关系。在动画和动画控制器中，所有对特效的引用都将使用这些简称。</br><h2></h2>
<br / ><textarea readonly="true" cols="47" rows="17">

{
  "format_version": "1.8.0",
  "minecraft:client_entity": {
    "description": {
      "identifier": "minecraft:entity_name",
      ...
       "particle_effects": {
            "shorthand_name1": "effect_name1",
            "shorthand_name2": "effect_name2",
        },
        ...
    }
  }
}

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<h1><p id="Effect List (continued)">效果列表（持续）</p></h1>

这是烈焰人的火焰燃烧效果的一个例子。在实体资源定义的“description”部分中，我们可以添加一个“particle_effects”部分，其中包含一个键值对。键是实体中其他.json将引用的名称，而值是粒子效果的名称，如粒子效果的.json中所指定的。</br><h2></h2>
<br / ><textarea readonly="true" cols="59" rows="20">

{
  "format_version": "1.8.0",
  "minecraft:client_entity": {
    "description": {
      "identifier": "minecraft:blaze",

      ...

       "particle_effects": {
            "charged_flames": "minecraft:mobflame_emitter"
        },

        ...

    }
  }
}

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

<br><br>

<h1><p id="Particles Examples Pack">粒子示例包</p></h1>

https://aka.ms/MCParticlesPack</br></br>（使用说明）各类粒子特效示例详见上方链接，这些均为独立粒子特效的范例。需注意：Minecraft 原版安装包提供的粒子特效已针对游戏内使用进行专门优化，因此不宜直接作为参考范例。请查阅资源包中的示例文件，了解粒子系统的多种应用方式。</br></br>要在启用示例粒子包的情况下调用示例粒子，请打开控制台，键入“/particle name x y z”，其中 “name” 是粒子特效的名称，x/y/z 是粒子出现的坐标。</br></br>例如，输入指令 "/particle minecraft:example_smoke_puff 0 5 0" 将在世界原点（即世界底部上方5格处）生成一团烟雾粒子特效。</br>输入指令 "/particle minecraft:example_smoke_puff ~ ~1 ~5" 将在玩家当前位置（前方5格，上方1格处）生成烟雾粒子特效。</br><h2>示例效果</h2>

<table border="1" style="width:100%; border-style:solid; border-collapse:collapse; border-width:3;">
<tr> <th style="border-style:solid; border-width:3;">名称</th> <th style="border-style:solid; border-width:3;">描述</th> </tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_bezier_chaincurve</td>
<td style="border-style:solid; border-width:3; padding:7px">演示如何在特效中使用贝塞尔链曲线</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_beziercurve</td>
<td style="border-style:solid; border-width:3; padding:7px">演示如何在特效中使用贝塞尔曲线。</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_blendmode_add</td>
<td style="border-style:solid; border-width:3; padding:7px">演示采用 particles_add 材质实现的渐变透明度纹理效果。</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_blendmode_alpha</td>
<td style="border-style:solid; border-width:3; padding:7px">演示采用 particles_alpha 材质实现的动态透明度纹理效果。</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_blendmode_blend</td>
<td style="border-style:solid; border-width:3; padding:7px">演示采用 particles_blend 混合材质实现的动态不透明度纹理效果。</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_bounce</td>
<td style="border-style:solid; border-width:3; padding:7px">演示粒子碰撞检测与反弹效果的实现。</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_catmullromcurve</td>
<td style="border-style:solid; border-width:3; padding:7px">演示在特效中运用 Catmull-Rom 曲线。</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_colorcurve</td>
<td style="border-style:solid; border-width:3; padding:7px">演示在特效中运用色彩梯度（color-gradient）实现颜色变化。</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_colorcurve2</td>
<td style="border-style:solid; border-width:3; padding:7px">演示特效中采用可变间距色彩梯度（color-gradient）。</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_combocurve</td>
<td style="border-style:solid; border-width:3; padding:7px">演示如何在特效中使用各种曲线</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_directional_sphere</td>
<td style="border-style:solid; border-width:3; padding:7px">演示如何在特效中使用定向公告板朝向控制。</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_entity_sparkle_aabb</td>
<td style="border-style:solid; border-width:3; padding:7px">当该特效绑定到实体时，会在实体的大致轴对齐边界框（AABB）范围内生成闪烁粒子效果。</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_entity_sparkle_box</td>
<td style="border-style:solid; border-width:3; padding:7px">当该特效绑定到实体时，会在实体周围形成一个盒状区域的闪烁粒子效果。</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_expire_on_contact</td>
<td style="border-style:solid; border-width:3; padding:7px">演示粒子在与地形碰撞时消失</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_flipbook</td>
<td style="border-style:solid; border-width:3; padding:7px">演示纹理UV翻页动画技术——通过连续切换纹理帧实现视觉动画效果。</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_highrestitution</td>
<td style="border-style:solid; border-width:3; padding:7px">演示粒子碰撞效果——粒子每次弹跳时能量递增的物理模拟实现。</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_linearcurve</td>
<td style="border-style:solid; border-width:3; padding:7px">演示特效中分段线性曲线（piecewise linear curve）的应用实现。</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_particle_event_system</td>
<td style="border-style:solid; border-width:3; padding:7px">演示执行各种粒子事件</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_smoke_puff</td>
<td style="border-style:solid; border-width:3; padding:7px">演示通用烟雾喷散（smoke puff）效果的实现方法。</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_spiral</td>
<td style="border-style:solid; border-width:3; padding:7px">演示参数化螺旋运动（parametric motion spiral）特效的实现方法。</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:example_watertest</td>
<td style="border-style:solid; border-width:3; padding:7px">演示如何从各种方块类型中排除粒子，在这种情况下，粒子只能在水中存留</br></td>
</tr>
<tr>
<td style="border-style:solid; border-width:3; padding:7px">minecraft:fireworks_events_demo</td>
<td style="border-style:solid; border-width:3; padding:7px">演示通过事件序列触发多种粒子效果，最终合成烟花特效的实现方法。</br></td>
</tr>
</table>
<a href="#Index">返回顶部</a><br><br>

<br><br>

<h1><p id="Structure In Detail">详细的结构</p></h1>

<h2></h2>
纲要：<br / ><textarea readonly="true" cols="100" rows="32">

{
  // specifies the format version of the particle.  Only particles of a particular set of versions 
  // will work with the game
  "format_version": "1.10.0",

  "particle_effect": {
    // general data for the particle effect
    "description": {
      // e.g. "minecraft:test_mule", this is the name the particle emitter is referred to as
      "identifier": <string>, 

      // Basic render parameters are basic rendering 
      // properties like the texture used, or the material used.
      // All particles require a material to render, and a 
      // texture to draw.  
      "basic_render_parameters": {
          "material": <string>
          "texture": <string>
      },
    },

    "curves": {
    // curves are described elsewhere in the document
    },

    "events": {
      // events are described elsewhere in the document
    },

    "components: {
        /////////////////////////////////////////////////////////////////////
        // Emitter related components
        // these components primarily affect the emitter bevahior

        // emitter initial state components set up the emitter with
        // particular properties

        // emitter rate components control when particles get emitted
        // these will be run every frame for the emitter to determine if any 
        // particles need to be spawned

        // emitter lifetime components control the lifetime of the emitter
        // and the "enabled/disabled" state of the emitter.
        // Emitters can only spawn particles if enabled.

        // emitter shapecomponents control where a particle gets emitted
        // and initial shape-driven state such as particle direction

        // emitter local space components
        // this component specifies whether entity-based emitters 
        // simulate in local or global space

        /////////////////////////////////////////////////////////////////////
        // Particle related components
        // these components primarily affect the particle behavior

        // particle initial condition components control what the initial state
        // of the particles is, such as initial speed, rotation, etc.
        // These are run once at particle creation

        // particle motion components control what happens to the particle
        // on frames after creation, such as it's position (for
        // a parametric particle), drag/acceleration (for a dynamic
        // particle), etc.
        // These are run once per frame per particle

        // particle appearance components control how the particle is rendered 
        // such as what UV coortinates to use, size of the particle,
        // billboard orientation, color tinting, etc.
        // These are run once per frame for visible particles

        // these components handle when the particle expires
    }
  }
}

</textarea> </br>
<a href="#Index">返回顶部</a><br><br>

